import shutil
from pathlib import Path
from fastapi import HTTPException


class FileView:
    """文件管理"""

    BaseDir = Path('fileserver')

    @classmethod
    def valid_directory(cls, path: str):
        path = (cls.BaseDir / path).resolve()
        if cls.BaseDir.resolve() not in path.parents and cls.BaseDir.resolve() != path.resolve():
            raise HTTPException(status_code=400, detail='无效路径')
        return path

    @classmethod
    def list_directory(cls, directory=None):
        directory = cls.valid_directory(directory)
        if not directory.exists():
            raise HTTPException(status_code=404, detail='目录不存在')
        if not directory.is_dir():
            raise HTTPException(status_code=400, detail='无效目录')

        return [{'filename': item.name,
                 'type': 'directory' if item.is_dir() else 'file',
                 'size': item.stat().st_size if item.is_file() else 0,
                 'modified': int(item.stat().st_mtime * 1000) - 3600 * 8 * 1000  # 转utc时区
                 } for item in directory.iterdir()]

    @classmethod
    def post_directory(cls, directory=None):
        directory = cls.valid_directory(directory)
        directory.mkdir(parents=True, exist_ok=True)
        return {}

    @classmethod
    def delete_directory(cls, directory=None):
        directory = cls.valid_directory(directory)
        if not directory.exists():
            raise HTTPException(status_code=404, detail='目录不存在')
        if not directory.is_dir():
            raise HTTPException(status_code=400, detail='无效目录')

        shutil.rmtree(directory)
        return {}

    @classmethod
    def get_file(cls, directory=None, filename=None):
        directory = cls.valid_directory(directory)
        filepath = (directory / filename).resolve()
        if not filepath.exists():
            raise HTTPException(status_code=404, detail='文件不存在')
        if not filepath.is_file():
            raise HTTPException(status_code=400, detail='无效文件')
        return dict(path=filepath, filename=filename)

    @classmethod
    def post_file(cls, directory, files=None):
        directory = cls.valid_directory(directory)
        for file in files:
            with open((directory / file.filename), 'wb') as w:
                shutil.copyfileobj(file.file, w)
        return {}

    @classmethod
    def delete_file(cls, path=None, filenames=None):
        path = cls.valid_directory(path)

        for filename in filenames:
            filepath = (path / filename).resolve()
            if not filepath.exists():
                continue
            if filepath.is_file():
                filepath.unlink(missing_ok=True)
        return {}


FileView.BaseDir.mkdir(exist_ok=True)  # 确保目录存在
